package Main;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.ImageIcon;
import javax.swing.KeyStroke;

import java.awt.FileDialog;
import java.awt.Toolkit;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/**
 * This class provides methods for manipulating individual pixels of an image.
 * The original image can be read from a file in JPEG, GIF, or PNG format, or
 * the user can create a blank image of a given size. This class includes
 * methods for displaying the image in a window on the screen or saving to a
 * fie.
 * <p>
 * Pixel (x, y) is column x, row y, where (0, 0) is upper left.
 * <p>
 * For additional documentation, see <a
 * href="http://www.cs.princeton.edu/introcs/31datatype">Section 3.1</a> of
 * <i>Introduction to Programming in Java: An Interdisciplinary Approach</i> by
 * Robert Sedgewick and Kevin Wayne.
 */
public final class Picture implements ActionListener {
 public BufferedImage image; // the rasterized image
 private JFrame frame; // on-screen view
 private String filename; // name of file
 private static int[][] source; //for the sobelmask
 
 /*
  * Create an empty w-by-h picture.
  */
 public Picture(int w, int h, String Title) {
  image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
  // set to TYPE_INT_ARGB to support transparency
  filename = Title;
 }

 /**
  * Create a picture by reading in a .png, .gif, or .jpg from the given
  * filename or URL name.
  */
 public Picture(String filename) {
  this.filename = filename;
  try {
   // try to read from file in working directory
   File file = new File(filename);
   if (file.isFile()) {
    image = ImageIO.read(file);
   }

   // now try to read from file in same directory as this .class file
   else {
    URL url = getClass().getResource(filename);
    if (url == null) {
     url = new URL(filename);
    }
    image = ImageIO.read(url);
   }
  } catch (IOException e) {
   // e.printStackTrace();
   throw new RuntimeException("Could not open file: " + filename);
  }

  // check that image was read in
  if (image == null) {
   throw new RuntimeException("Invalid image file: " + filename);
  }
 }
 /**
  * Create a picture by reading in a .png, .gif, or .jpg from a File.
  */
 public Picture(File file) {
  try {
   image = ImageIO.read(file);
  } catch (IOException e) {
   e.printStackTrace();
   throw new RuntimeException("Could not open file: " + file);
  }
  if (image == null) {
   throw new RuntimeException("Invalid image file: " + file);
  }
 }
 public Picture(BufferedImage img, String title) {
	 image = img;
	 filename = title;
	// TODO Auto-generated constructor stub
}

/**
  * Return a JLabel containing this Picture, for embedding in a JPanel,
  * JFrame or other GUI widget.
  */
 public JLabel getJLabel() {
  if (image == null) {
   return null;
  } // no image available
  ImageIcon icon = new ImageIcon(image);
  return new JLabel(icon);
 }
 /**
  * Display the picture in a window on the screen.
  */
 public void show() {

  // create the GUI for viewing the image if needed
  if (frame == null) {
   frame = new JFrame();

   JMenuBar menuBar = new JMenuBar();
   JMenu menu = new JMenu("File");
   menuBar.add(menu);

   JMenuItem menuItem1 = new JMenuItem(" Save...   ");
   menuItem1.addActionListener(this);
   menuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
     Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
   menu.add(menuItem1);
   /**** add file open option *****/

   frame.setJMenuBar(menuBar);
   if (image != null)
    frame.setContentPane(getJLabel());

   frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
   frame.setTitle(filename);
   frame.setResizable(false);
   frame.pack();
   frame.setVisible(true);
  }
  // draw
  frame.repaint();
 }
 /**
  * Return the height of the picture (in pixels).
  */
 public int height() {
  return image.getHeight(null);
 }
 /**
  * Return the width of the picture (in pixels).
  */
 public int width() {
  return image.getWidth(null);
 }
 /**
  * Return the Color of pixel (i, j).
  */
 public Color get(int i, int j) {
  return new Color(image.getRGB(i, j));
 }
 /**
  * Set the Color of pixel (i, j) to c.
  */
 public void set(int i, int j, Color c) {
  if (c == null) {
   throw new RuntimeException("can't set Color to null");
  }
  image.setRGB(i, j, c.getRGB());
 }
 /**
  * Save the picture to a file in a standard image format. The file type must
  * be .png or .jpg.
  */
 public void save(String name) {
  save(new File(name));
 }
 /**
  * Save the picture to a file in a standard image format.
  */
 public void save(File file) {
  this.filename = file.getName();
  if (frame != null) {
   frame.setTitle(filename);
  }
  String suffix = filename.substring(filename.lastIndexOf('.') + 1);
  suffix = suffix.toLowerCase();
  if (suffix.equals("jpg") || suffix.equals("png")) {
   try {
    ImageIO.write(image, suffix, file);
   } catch (IOException e) {
    e.printStackTrace();
   }
  } else {
   System.out.println("Error: filename must end in .jpg or .png");
  }
 }
 /**
  * getColors
  * Creates a two dimensional Color array representation of the image
  * @return two dimensional Color array
  */
 public Color[][] getColors() {
	 int w = width();
		int h = height();
		Color[][] c = new Color[h][w];
		for(int y = 0; y < h; y++)
			for(int x = 0; x < w; x++)
				c[y][x] = get(x, y);
		return c;
	}
 /**
  * setColors
  * Replaces the current image with the colors passed to the parameter.
  * @param c a two dimensional Color array used to update the image
  */
public void setColors(Color[][] c){
	int w = c[0].length;
	int h = c.length;
	for(int y = 0; y < h; y++)
		for(int x = 0; x < w; x++)
			set(x, y, c[y][x]);
	}
public Color[][] removeRed(Color[][] c) {
	int w = c[0].length;
	int h = c.length;
	for(int y = 0; y < h; y++){
		for(int x = 0; x < w; x++){
			Color r = c[y][x];
			c[y][x] = new Color(0, r.getGreen(), r.getBlue());
	}
		}
	return c;
}

public static Color[][] averageRGB(Color[][] c) {
	int w = c[0].length;
	int h = c.length;
	source = new int[h][w]; 
	for(int y = 0; y < h; y++){
		for(int x = 0; x < w; x++){
			Color r = c[y][x];
			int average = (r.getRed() + r.getGreen() + r.getBlue())/3;
			source[y][x] = average;
			c[y][x] = new Color(average, average, average);
	}
		}
	return c;
}

public Color[][] peakRGB(Color[][] c) {
	int w = c[0].length;
	int h = c.length;
	int red,g,b,peak = 0;
	for(int y = 0; y < h; y++){
		for(int x = 0; x < w; x++){
			Color r = c[y][x];
			red = r.getRed();
			g = r.getGreen();
			b = r.getBlue();
			if (red > g & red > b) peak = red;
			else if (g > red & g > b) peak = g;
			else if (b > red & b > g) peak = b;
			c[y][x] = new Color(peak, peak, peak);
	}
		}
	return c;
}

public Color[][] luminance(Color[][] c) {
	int w = c[0].length;
	int h = c.length;
	int red,g,b;
	for(int y = 0; y < h; y++){
		for(int x = 0; x < w; x++){
			Color r = c[y][x];
			red = (int)Math.ceil(r.getRed() * .3);
			g = (int)Math.ceil(r.getBlue() * .59);
			b = (int)Math.ceil(r.getGreen() * .11);
			c[y][x] = new Color(red, g, b);
	}
		}
	return c;
}

 /**
  * removeRed
  * Removes the red pixel from each Color object in the parameter
  * @param c a two dimensional Color array to be modified
  * @return the modified two dimensional Color array
  */
 /**
  * Opens a save dialog box when the user selects "Save As" from the menu.
  */
public void actionPerformed(ActionEvent e) {
  FileDialog chooser = new FileDialog(frame,
    "Use a .png or .jpg extension", FileDialog.SAVE);
  chooser.setVisible(true);
  if (chooser.getFile() != null) {
   save(chooser.getDirectory() + File.separator + chooser.getFile());
  }
 } 

 

		}//end

